use std::cell::{Cell, RefCell};
use std::rc::Rc;

use crate::gen_title;

pub fn ch4_9_1() {
    gen_title("ch4_9_1", 18);

    let c = Cell::new("asdf");
    let one = c.get();
    c.set("qwer");
    let two = c.get();
    println!("{} {}", one, two);
}

pub fn ch4_9_2() {
    gen_title("ch4_9_2", 18);

    let s = RefCell::new(String::from("Hello, world"));
    let s1 = s.borrow();
    let s2 = s.borrow();

    println!("{} {}", s1, s2);
}

pub fn ch4_9_3() {
    gen_title("ch4_9_3", 18);

    let x = Cell::new(1);
    let y = &x;
    let z = &x;
    x.set(2);
    y.set(3);
    z.set(4);
    println!("{}", x.get());

    let mut x = 1;
    let y = &mut x;
    *y = 3;
    println!("{}", x);
}

pub fn ch4_9_4() {
    gen_title("ch4_9_4", 18);

    pub trait Messenger {
        fn send(&self, msg: String);
    }

    struct MsgQueue {
        msg_cache: RefCell<Vec<String>>,
    }

    impl Messenger for MsgQueue {
        fn send(&self, msg: String) {
            self.msg_cache.borrow_mut().push(msg);
        }
    }

    let mq = MsgQueue {
        msg_cache: RefCell::new(vec![]),
    };
    mq.send("hello, world".to_string());
    println!("{:?}", mq.msg_cache);
}

pub fn ch4_9_5() {
    gen_title("ch4_9_5", 18);

    let s = Rc::new(RefCell::new("我很善变, 还有多个主人".to_string()));

    let s1 = s.clone();
    let s2 = s.clone();
    s2.borrow_mut().push_str(", oh yeah!!!");

    println!("{:?}\n{:?}\n{:?}", s, s1, s2);
}

pub fn ch4_9_6() {
    gen_title("ch4_9_6", 18);

    fn is_even(i: i32) -> bool {
        i % 2 == 0
    }

    fn retain_even(nums: &mut Vec<i32>) {
        let slice: &[Cell<i32>] = Cell::from_mut(&mut nums[..]).as_slice_of_cells();
        let mut i = 0;
        for num in slice.iter().filter(|&num| is_even(num.get())) {
            slice[i].set(num.get());
            i += 1;
        }
        nums.truncate(i);
    }

    let n = &mut vec![1, 2, 2, 3, 4, 5];
    retain_even(n);
    println!("{:?}", n);
}
